﻿using movie.tool.library.hash;
using movie.tool.library.ui;
using movie.tool.module.film.model;
using movie.tool.module.film.service;
using movie.tool.module.http;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows;

namespace movie.tool.module.film.ui
{
    /// <summary>
    /// MoviePublishControl.xaml 的交互逻辑
    /// </summary>
    public partial class MoviePublishControl : BaseControl
    {
        public static readonly DependencyProperty ConfigProperty = DependencyProperty.Register("Config", typeof(MovieProject), typeof(MoviePublishControl));
        public MovieProject Config
        {
            get => (MovieProject)GetValue(ConfigProperty);
            set => SetValue(ConfigProperty, value);
        }

        public static readonly DependencyProperty BusyInfoProperty = DependencyProperty.Register("BusyInfo", typeof(BusyInfo), typeof(MoviePublishControl));
        public BusyInfo BusyInfo
        {
            get => (BusyInfo)GetValue(BusyInfoProperty);
            set => SetValue(BusyInfoProperty, value);
        }

        private MoviePublishParam moviePublishParam;
        public MoviePublishParam MoviePublishParam
        {
            get => moviePublishParam;
            set
            {
                moviePublishParam = value;
                SendPropertyChanged(nameof(MoviePublishParam));
            }
        }
        public Visibility SaveVisibility
        {
            get
            {
                if (Config != null && Config.ImportProject)
                {
                    return Visibility.Visible;
                }
                else
                {
                    return Visibility.Collapsed;
                }
            }
        }

        public HorizontalAlignment PublishHorizontalAlignment
        {
            get
            {
                if (Config != null && Config.ImportProject)
                {
                    return HorizontalAlignment.Right;
                }
                else
                {
                    return HorizontalAlignment.Center;
                }
            }
        }
        public MoviePublishControl()
        {
            InitializeComponent();
            MoviePublishParam = new MoviePublishParam();
        }

        private async void MoviePublishClick(object sender, RoutedEventArgs e)
        {
            try
            {
                BusyInfo.Busy = true;
                BusyInfo.DefaultMessage();
                TaskKey key = await MovieClient.publish(MoviePublishParam, Config.Id);
                if(key != null)
                {
                    //获取进度
                    TaskProgress tp = await MovieClient.LoadProgress(key);
                    while(tp != null && !tp.Succeed() && !tp.Failed())
                    {
                        BusyInfo.BusyMessage = tp.Message;
                        tp = await MovieClient.LoadProgress(key);
                    }
                    if(tp == null)
                    {
                        MessageBox.Show("获取进度超时,请稍候查看是否发布成功");
                    }
                    else
                    {
                        if (tp.Succeed())
                        {
                            MessageBox.Show("发布成功");
                        }
                        else
                        {
                            MessageBox.Show(tp.Message);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("未获取到请求结果,请稍候查看是否发布成功");
                }
            }
            finally
            {
                BusyInfo.Reset();
            }
        }

        private async void MovieSaveClick(object sender, RoutedEventArgs e)
        {
            try
            {
                BusyInfo.Busy = true;
                BusyInfo.DefaultMessage();
                string rootPath = MovieService.ProjectJsonFilePath(Config.Id);
                BusyInfo.BusyMessage = "正在保存剧本信息";
                bool ret = await MovieClient.UpdateMovieInfo(Config.Movie, Config.Id);
                if (!ret)
                {
                    return;
                }
                BusyInfo.BusyMessage = "正在保存封面";
                ret = await MovieClient.UpdateMovieCover(Path.Join(rootPath, Config.Movie.Cover), Config.Movie.Cover, Config.Id);
                if (!ret)
                {
                    return;
                }
                if (!string.IsNullOrWhiteSpace(Config.Movie.Assist))
                {
                    BusyInfo.BusyMessage = "正在保存剧本手册";
                    ret = await MovieClient.UpdateMovieAssist(Path.Join(rootPath, Config.Movie.Assist), Config.Movie.Assist, Config.Id);
                    if (!ret)
                    {
                        return;
                    }
                }
                if (Config.Scenes != null && Config.Scenes.Count > 0)
                {
                    foreach(SceneConfig sc in Config.Scenes)
                    {
                        BusyInfo.BusyMessage = "正在保存剧幕" + sc.Name;
                        ret = await SaveMovieScene(sc);
                        if (!ret)
                        {
                            return;
                        }
                    }
                }
                if(Config.ClueCardGroups != null && Config.ClueCardGroups.Count > 0)
                {
                    foreach(ClueCardGroupConfig item in Config.ClueCardGroups)
                    {
                        ret = await SaveClueCardGroup(item);
                        if (!ret)
                        {
                            return;
                        }
                    }
                }
                if(Config.Roles != null && Config.Roles.Count > 0)
                {
                    foreach(PlayerRoleConfig item in Config.Roles)
                    {
                        BusyInfo.BusyMessage = "正在保存角色" + item.Name;
                        ret = await SavePlayerRole(item);
                        if (!ret)
                        {
                            return;
                        }
                    }
                }
                if(Config.Chapters!=null && Config.Chapters.Count > 0)
                {
                    foreach(BookChapter chapter in Config.Chapters)
                    {
                        BusyInfo.BusyMessage = "正在保存章节" + chapter.Name;
                        ret = await SaveChapter(chapter);
                        if (!ret)
                        {
                            return;
                        }
                    }
                }
                if(Config.Books != null && Config.Books.Count > 0)
                {
                    foreach(PlayRoleBookConfig book in Config.Books)
                    {
                        BusyInfo.BusyMessage = "正在上传电子书文件" + book.Name;
                        ret = await SaveBook(book);
                        if (!ret)
                        {
                            return;
                        }
                    }
                }
                MovieService.SaveProjectMovie(Config);
            }
            finally
            {
                BusyInfo.Reset();
            }
        }
        private async Task<bool> SaveBook(PlayRoleBookConfig book)
        {
            string rootPath = MovieService.ProjectJsonFilePath(Config.Id);
            string filePath = Path.Join(rootPath, book.FilePath);

            if (File.Exists(filePath))
            {
                if (!await MovieClient.BookFileEquals(filePath, book.Id))
                {
                    PlayerRoleConfig role = book.PlayRoleId > 0 ? Config.FindRole(book.PlayRoleId) : Config.FindRole(book.RoleName);
                    if(role == null)
                    {
                        MessageBox.Show("角色" + book.RoleName + "未找到");
                        return false;
                    }
                    BookChapter chapter = book.ChapterId > 0 ? Config.FindChapter(book.ChapterId) : Config.FindChapter(book.Name);
                    if(chapter == null)
                    {
                        MessageBox.Show("章节" + book.Name + "未找到");
                        return false;
                    }
                    //文件不一样,那上传文件
                    long? res = await MovieClient.UploadBookFile(filePath, role.Id, chapter.Id, book.FilePath);
                    if (res is not null and > 0)
                    {
                        book.Id = (long)res;
                        book.PlayRoleId = role.Id;
                        book.ChapterId = chapter.Id;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        private async Task<bool> SaveChapter(BookChapter chapter)
        {
            if (chapter.Id > 0)
            {
                bool ret = await MovieClient.UpdateChapter(chapter);
                if (!ret)
                {
                    return false;
                }
            }
            else
            {
                long? id = await MovieClient.SaveChapter(chapter, Config.Id);
                if (id is not null and > 0)
                {
                    chapter.Id = (long)id;
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
        private async Task<bool> SavePlayerRole(PlayerRoleConfig role)
        {
            if (role.Id > 0)
            {
                bool ret = await MovieClient.UpdatePlayerRole(role);
                if (!ret)
                {
                    return false;
                }
            }
            else
            {
                long? id = await MovieClient.SavePlayerRole(role, Config.Id);
                if (id is not null and > 0)
                {
                    role.Id = (long)id;
                }
                else
                {
                    return false;
                }
            }
            string rootPath = MovieService.ProjectJsonFilePath(Config.Id);
            string filePath = Path.Join(rootPath, role.FilePath);
            if (File.Exists(filePath))
            {
                if (!await MovieClient.PlayerRoleFileEquals(filePath, role.Id))
                {
                    //文件不一样,那上传文件
                    bool res = await MovieClient.UploadPlayerRoleFile(filePath, role.Id, role.FilePath);
                    if (!res)
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        private async Task<bool> SaveClueCardGroup(ClueCardGroupConfig item)
        {
            BusyInfo.BusyMessage = "正在保存线索分组" + item.Name;
            if (item.Id > 0)
            {
                bool ret = await MovieClient.UpdateClueCardGroup(item);
                if (!ret)
                {
                    return false;
                }
            }
            else
            {
                long? id = await MovieClient.SaveClueCardGroup(item, Config.Id);
                if (id is not null and > 0)
                {
                    item.Id = (long)id;
                }
                else
                {
                    return false;
                }
            }
            if (item.ClueCards != null && item.ClueCards.Count > 0)
            {
                foreach (ClueCardConfig clueCard in item.ClueCards)
                {
                    BusyInfo.BusyMessage = "正在保存线索" + clueCard.Name;
                    bool ret = await SaveClueCard(item, clueCard);
                    if (!ret)
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        /// <summary>
        /// 保存线索信息及上传线索文件
        /// </summary>
        /// <param name="item">线索分组</param>
        /// <param name="clueCard">线索信息</param>
        /// <returns>继续后续操作返回true,返回false则停止继续</returns>
        private async Task<bool> SaveClueCard(ClueCardGroupConfig item, ClueCardConfig clueCard)
        {
            if(clueCard == null)
            {
                return true;
            }
            if(clueCard.Id > 0)
            {
                bool ret = await MovieClient.UpdateClueCard(clueCard);
                if (!ret)
                {
                    return false;
                }
            }
            else
            {
                long? id = await MovieClient.SaveClueCard(clueCard, item.Id);
                if(id is not null and > 0)
                {
                    clueCard.Id = (long)id;
                    clueCard.Group = item.Id;
                }
                else
                {
                    return false;
                }
            }
            string rootPath = MovieService.ProjectJsonFilePath(Config.Id);
            //查看高清文件是否修改
            if (!string.IsNullOrEmpty(clueCard.HdFile))
            {
                string filePath = Path.Join(rootPath, clueCard.HdFile);
                if (File.Exists(filePath))
                {
                    if (!await MovieClient.ClueCardHdFileEquals(filePath, clueCard.Id))
                    {
                        //文件不一样,那上传文件
                        bool ret = await MovieClient.UploadClueCardHdFile(filePath, clueCard.Id, clueCard.HdFile);
                        if (!ret)
                        {
                            return false;
                        }
                    }
                }
            }

            //查看高清文件是否修改
            if (!string.IsNullOrEmpty(clueCard.SdFile))
            {
                string filePath = Path.Join(rootPath, clueCard.SdFile);
                if (File.Exists(filePath))
                {
                    if (!await MovieClient.ClueCardSdFileEquals(filePath, clueCard.Id))
                    {
                        //文件不一样,那上传文件
                        bool ret = await MovieClient.UploadClueCardSdFile(filePath, clueCard.Id, clueCard.SdFile);
                        if (!ret)
                        {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// 保存剧幕
        /// </summary>
        /// <param name="sc">剧幕信息</param>
        /// <returns>返回true则继续后续操作,false则停止</returns>
        private async Task<bool> SaveMovieScene(SceneConfig sc)
        {
            if (sc.Id > 0)
            {
                //修改
                bool ret = await MovieClient.UpdateScene(sc);
                if (!ret)
                {
                    return false;
                }
            }
            else
            {
                long? id = await MovieClient.SaveScene(sc, Config.Id);
                if (id is not null and > 0)
                {
                    sc.Id = (long)id;
                }
                else
                {
                    return false;
                }
            }
            if (string.IsNullOrWhiteSpace(sc.File))
            {
                return true;
            }
            string rootPath = MovieService.ProjectJsonFilePath(Config.Id);
            string filePath = Path.Join(rootPath, sc.File);
            if (File.Exists(filePath))
            {
                string digest = await MovieClient.SceneFileDigest(sc.Id);
                string localDigest = SHA1Hash.FileDigest(filePath);
                if (!localDigest.Equals(digest))
                {
                    //文件不一样,那上传文件，先Obs上传
                    FileDigestParam param = new FileDigestParam();
                    param.Sha1 = localDigest;
                    param.FileName = Path.GetFileName(filePath);
                    param.Path = sc.File;
                    bool res = await MovieClient.UploadSceneFileObs(filePath, sc.Id, param);
                    if (!res)
                    {
                        // 再偿试从服务端上传
                        res = await MovieClient.UploadSceneFile(filePath, sc.Id);
                    }
                    if (!res)
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        private void BaseControl_Loaded(object sender, RoutedEventArgs e)
        {
            SendPropertyChanged(nameof(SaveVisibility));
            SendPropertyChanged(nameof(PublishHorizontalAlignment));
        }
    }
}
